package com.example.travelgd.service;

import com.example.travelgd.entity.Carousel;
import com.example.travelgd.repository.CarouselMapper;
import com.example.travelgd.util.FwResult;
import com.example.travelgd.websocket.WebSocketServer;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class CarouselService {

    @Autowired
    private CarouselMapper carouselMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private WebSocketServer webSocketServer;

    private static final String CAROUSEL_CACHE_KEY = "travelgd:carousel:list";
    private static final long CACHE_EXPIRE_TIME = 5; // 5分钟
    private static final TimeUnit CACHE_EXPIRE_UNIT = TimeUnit.MINUTES;

    public List<Carousel> getCarouselList() {
        // 先从缓存获取
        List<Carousel> cachedList = (List<Carousel>) redisTemplate.opsForValue().get(CAROUSEL_CACHE_KEY);
        if (cachedList != null) {
            log.info("从缓存获取的数据: {}", cachedList);
            return cachedList;
        }

        // 缓存未命中,从数据库查询
        List<Carousel> carouselList = carouselMapper.selectAllEnabled();
        log.info("从数据库获取的数据: {}", carouselList);

        // 放入缓存,使用配置的过期时间
        redisTemplate.opsForValue().set(CAROUSEL_CACHE_KEY, carouselList,
                CACHE_EXPIRE_TIME, CACHE_EXPIRE_UNIT);

        return carouselList;
    }

    public FwResult<Void> addCarousel(Carousel carousel) {
        try {
            // 设置默认值
            carousel.setSort(carousel.getSort() == null ? 0 : carousel.getSort());
            carousel.setStatus(carousel.getStatus() == null ? 1 : carousel.getStatus());

            if (carouselMapper.insert(carousel) > 0) {
                // 清除缓存并重新加载
                refreshCache();
                // 推送更新消息
                webSocketServer.sendToAll("CAROUSEL_UPDATE");
                log.info("轮播图添加成功并推送更新消息，ID: {}", carousel.getId());
                return FwResult.ok();
            }
            return FwResult.failedMsg("添加轮播图失败");
        } catch (Exception e) {
            log.error("添加轮播图失败", e);
            return FwResult.failedMsg("添加轮播图失败");
        }
    }

    public FwResult<Void> updateCarousel(Carousel carousel) {
        try {
            if (carouselMapper.updateById(carousel) > 0) {
                // 立即清除缓存
                clearCache();
                // 立即推送更新消息
                webSocketServer.sendToAll("CAROUSEL_UPDATE");
                return FwResult.ok();
            }
            return FwResult.failedMsg("更新轮播图失败");
        } catch (Exception e) {
            log.error("更新轮播图失败", e);
            return FwResult.failedMsg("更新轮播图失败");
        }
    }

    public FwResult<Void> deleteCarousel(Long id) {
        try {
            if (carouselMapper.deleteById(id) > 0) {
                // 清除缓存并重新加载
                refreshCache();
                // 推送更新消息
                webSocketServer.sendToAll("CAROUSEL_UPDATE");
                log.info("轮播图删除成功并推送更新消息，ID: {}", id);
                return FwResult.ok();
            }
            return FwResult.failedMsg("删除轮播图失败");
        } catch (Exception e) {
            log.error("删除轮播图失败", e);
            return FwResult.failedMsg("删除轮播图失败");
        }
    }

    public void clearCache() {
        try {
            redisTemplate.delete(CAROUSEL_CACHE_KEY);
            log.info("轮播图缓存已清除");
        } catch (Exception e) {
            log.error("清除轮播图缓存失败", e);
        }
    }

    public void refreshCache() {
        try {
            clearCache();
            List<Carousel> carouselList = carouselMapper.selectAllEnabled();
            redisTemplate.opsForValue().set(CAROUSEL_CACHE_KEY, carouselList,
                    CACHE_EXPIRE_TIME, CACHE_EXPIRE_UNIT);
            log.info("轮播图缓存已刷新");
            // 推送更新消息
            webSocketServer.sendToAll("CAROUSEL_UPDATE");
        } catch (Exception e) {
            log.error("刷新轮播图缓存失败", e);
        }
    }

    public boolean isCacheValid() {
        try {
            return redisTemplate.hasKey(CAROUSEL_CACHE_KEY);
        } catch (Exception e) {
            log.error("检查缓存状态失败", e);
            return false;
        }
    }
}